package com.chkj.fbook.system.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.chkj.fbook.common.utils.SessionPermission;
import com.chkj.fbook.common.utils.SessionUtils;
import com.chkj.fbook.common.utils.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.chkj.fbook.common.annotation.Permission;
import com.chkj.fbook.system.domain.UserDO;

/**
 * @TODO: 权限拦截器
 * @author: shh_he
 * @date: 2023年10月1日上午11:31:30
 */
public class PermissionInterceptor implements HandlerInterceptor {

	private static final Logger log = LoggerFactory.getLogger(PermissionInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		if (handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();
			String ctx = WebUtils.getContextPath(request);
			
			// 2：登录校验已成功后才会判断是否需要进行权限校验，方法前是否有权限注解，有就做权限匹配，没有就放行
			if (method.isAnnotationPresent(Permission.class)) {
				
				// 2、判断用户是否登录
				UserDO sessionUser = SessionUtils.getSessionUser(request);
				if (sessionUser == null) {
					PrintWriter out = response.getWriter();
					out.print("<script type='text/javascript'>top.location='" + ctx + "/login'</script>");
					out.close();
					return false;
				}

				// 取出注解的权限值
				Permission permission = method.getAnnotation(Permission.class);
				//获取登录用户权限列表
				SessionPermission sessionPermission = SessionUtils.getSessionPermission(request, "ssoServer");
				Set<String> userPermissions = new HashSet<String>();
				// 登录用户当前应用的权限
				userPermissions = sessionPermission.getPermissionSet();
				// 与系统管理员拥有的权限进行匹配
				boolean hasPrivilege = userPermissions.contains(permission.name());

				if (hasPrivilege) {// 拥有
					return true;
				} else {// 不 拥有
					log.info("您没有操作" + permission.name() + "的权限!");
					// 弹出警告
					responseJson(response, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "没有访问权限");
					return false;
				}
			}

		}

		return true;
	}

	protected void responseJson(HttpServletResponse response, int code, String message) throws IOException {
		response.setContentType("application/json;charset=UTF-8");
		response.setStatus(HttpStatus.OK.value());
		PrintWriter writer = response.getWriter();
		writer.write(new StringBuilder().append("{\"code\":").append(code).append(",\"msg\":\"").append(message)
				.append("\"}").toString());
		writer.flush();
		writer.close();
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}

}
